#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
script usage:
    python copy.py -h
    python copy.py -f -i a.txt -o b.txt -d gb2312 -e utf-8
"""
import optparse
import os
import sys
from functools import partial


def accept_words(s, words):
    if words:
        for word in words:
            if word in s:
                return True
        return False
    return True


def convert_encoding(s, src, dest):
    ret = None
    if src:
        ret = s.decode(src)
        if dest:
            ret = ret.encode(dest)
    elif dest:
        ret = s.encode(dest)
    return ret


def copy(infile, outfile, accept=None, convert=None):
    with open(infile, 'r') as src, open(outfile, 'w') as dest:
        for line in src:
            if accept and not accept(line):
                continue
            if convert:
                line = convert(line)
            dest.write(line)


def _parse_args():
    parser = optparse.OptionParser()
    parser.add_option('-i', '--in', dest='infile', metavar='file',
        help='the input file path')
    parser.add_option('-o', '--out', dest='outfile', metavar='file',
        help='the output file path')
    parser.add_option('-f', '--force', dest='force', default=False,
        action='store_true', help='not ask if cover the output file')
    parser.add_option('-k', '--keep', dest='words',
        metavar='one,two', default=None,
        help='only copy the line which contains one of these words')
    parser.add_option('-d', '--decode', dest='decode_encoding', metavar='gb2312',
        help='decode encoding used to the line')
    parser.add_option('-e', '--encode', dest='encode_encoding', metavar='utf-8',
        help='encode encoding used to the line, after decode')
    options, args = parser.parse_args()
    # positional arguments are ignored
    return options


if __name__ == '__main__':
    options = _parse_args()

    infile = options.infile
    if not infile or not os.path.exists(infile):
        sys.exit('not found the input file: %s' % infile)

    outfile = options.outfile
    if not outfile:
        sys.exit('not specified the output file')

    if not options.force and os.path.exists(outfile):
        cover = raw_input('%s will be covered (y/n): ' % outfile)
        if cover.lower() == 'n':
            print('give up')
            sys.exit()

    accept = None
    convert = None

    if options.words:
        words = options.words.split(',')
        print('accept: %s' % words)
        accept = partial(accept_words, words=words)

    if options.decode_encoding or options.encode_encoding:
        print('convert: %s > %s' % (options.decode_encoding,
            options.encode_encoding))
        convert = partial(convert_encoding, src='gb2312', dest='utf-8')

    print('copying...')
    copy(options.infile, options.outfile, accept, convert)
    print('complete!')
